package edu.nf.llmtest.service.impl;

import com.alibaba.fastjson2.JSONObject;
import edu.nf.llmtest.service.WeatherService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ Author bin
 * @ Create  2025/11/3 23:07
 **/
@Service
@RequiredArgsConstructor
@Slf4j
public class WeatherServiceImpl implements WeatherService {
    // 天气情况查询接口地址
    private static final String API_URL = "http://apis.juhe.cn/simpleWeather/query";
    
    // 接口请求Key（从配置文件读取，默认值用于测试）
    @Value("${weather.api-key:e1901d5ed8edd138841bc564429b3890}")
    private String apiKey;

    @Override
    public String queryWeather(String cityName) {
        Map<String, Object> params = new HashMap<>();//组合参数
        params.put("city", cityName);
        params.put("key", apiKey);
        String queryParams = urlencode(params);

        String response = doGet(API_URL, queryParams);
        if (response == null) {
            log.error("天气查询失败：响应为空");
            return null;
        }
        
        try {
            JSONObject jsonObject = JSONObject.parseObject(response);
            int error_code = jsonObject.getIntValue("error_code");
            if (error_code == 0) {
                log.info("调用天气接口成功，城市：{}", cityName);
                return response;
            } else {
                String reason = jsonObject.getString("reason");
                log.error("调用天气接口失败：{}", reason);
                return null;
            }
        } catch (Exception e) {
            log.error("解析天气响应失败", e);
            return null;
        }
    }

    @Override
    public List<String> getWeatherByCityName(String cityName, String extensions) {
        String response = queryWeather(cityName);
        if (response == null) {
            return new ArrayList<>();
        }
        
        List<String> weatherInfo = new ArrayList<>();
        try {
            JSONObject jsonObject = JSONObject.parseObject(response);
            JSONObject result = jsonObject.getJSONObject("result");
            JSONObject realtime = result.getJSONObject("realtime");
            
            weatherInfo.add("城市：" + result.getString("city"));
            weatherInfo.add("天气：" + realtime.getString("info"));
            weatherInfo.add("温度：" + realtime.getString("temperature") + "℃");
            weatherInfo.add("湿度：" + realtime.getString("humidity"));
            weatherInfo.add("风向：" + realtime.getString("direct"));
            weatherInfo.add("风力：" + realtime.getString("power"));
            weatherInfo.add("空气质量：" + realtime.getString("aqi"));
        } catch (Exception e) {
            log.error("解析天气信息失败", e);
        }
        log.info("获取天气信息成功：{}", weatherInfo);
        return weatherInfo;
    }

    /**
     * get方式的http请求
     *
     * @param httpUrl 请求地址
     * @return 返回结果
     */
    private String doGet(String httpUrl, String queryParams) {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        String result = null;// 返回结果字符串
        try {
            // 创建远程url连接对象（使用URI避免URL构造函数废弃警告）
            URI uri = URI.create(httpUrl + "?" + queryParams);
            // 通过远程url连接对象打开一个连接，强转成httpURLConnection类
            connection = (HttpURLConnection) uri.toURL().openConnection();
            // 设置连接方式：get
            connection.setRequestMethod("GET");
            // 设置连接主机服务器的超时时间：15000毫秒
            connection.setConnectTimeout(5000);
            // 设置读取远程返回的数据时间：60000毫秒
            connection.setReadTimeout(6000);
            // 发送请求
            connection.connect();
            // 通过connection连接，获取输入流
            if (connection.getResponseCode() == 200) {
                inputStream = connection.getInputStream();
                // 封装输入流，并指定字符集
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
                // 存放数据
                StringBuilder sbf = new StringBuilder();
                String temp;
                while ((temp = bufferedReader.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append(System.getProperty("line.separator"));
                }
                result = sbf.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();// 关闭远程连接
            }
        }
        return result;
    }

    /**
     * 将map型转为请求参数型
     *
     * @param data 参数Map
     * @return URL编码后的参数字符串
     */
    private String urlencode(Map<String, ?> data) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, ?> i : data.entrySet()) {
            try {
                sb.append(i.getKey()).append("=").append(URLEncoder.encode(i.getValue() + "", "UTF-8")).append("&");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        String result = sb.toString();
        result = result.substring(0, result.lastIndexOf("&"));
        return result;
    }

    /**
     * 定义天气查询函数的Schema（供AI调用）
     * 
     * @return 函数定义Map，包含函数名称、描述和参数定义
     */
    public static Map<String, Object> functionSchema() {
        return Map.of(
                "name", "query_weather",
                "description", "根据城市名称查询实时天气信息，包括天气状况、温度、湿度、风向、风力、空气质量等",
                "parameters", Map.of(
                        "type", "object",
                        "properties", Map.of(
                                "cityName", Map.of(
                                        "type", "string",
                                        "description", "城市名称，例如：北京、上海、广州、重庆、成都等。支持全国主要城市"
                                )
                        ),
                        "required", List.of("cityName")
                )
        );
    }
}
